﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;

#if TVDP_UNITTESTING
using TvdP.UnitTesting;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif


using ObticsUnitTest.Helpers;
using Obtics.Collections.Transformations;
using Obtics.Collections;
using System.ComponentModel;
using Obtics.Collections.Patches;

namespace ObticsUnitTest.Obtics.Collections.Transformations
{
    /// <summary>
    /// Summary description for SequencingPatchTransformationTest
    /// </summary>
    [TestClass]
    public class SequencingPatchTransformationTest
    {
        public SequencingPatchTransformationTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        class CorrectnessRunner : CollectionTestSequenceRunnerForTransformation<string, string>
        {

            static List<string> source = new List<string>(
                new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }
            );

            public override List<string> SourceSequence
            {
                get { return source; }
            }

            public override List<string> ExpectedResult
            {
                get { return source; }
            }

            static List<string> filler = new List<string>(
                new string[] { "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }
            );

            public override List<string> FillerItems
            {
                get { return filler; }
            }

            public override IEnumerable<string> CreatePipeline(FrameIEnumerable<string> frame)
            {
                return StandardPatch<IEnumerable<string>,string>.Create(frame);
            }

            public override string Prefix
            {
                get { return "new SequencingPatchTransformation<string>(frame)"; }
            }
        }

        [TestMethod]
        public void CorrectnessTest()
        {
            var runner = new CorrectnessRunner();

            runner.RunAllPrepPairs();
        }

        class DeterministicEventRegistrationRunner : CollectionDeterministicEventRegistrationRunnerForTransformation<int, int>
        {
            protected override IEnumerable<int> CreateTransformation(FrameIEnumerableNPCNCC<int> frame)
            {
                return StandardPatch<IEnumerable<int>,int>.Create(frame);
            }

            public override string Prefix
            {
                get { return "new SequencingPatchTransformation<int>(frame)"; }
            }
        }

        [TestMethod]
        public void DeterministicEventRegistrationTest()
        {
            var runner = new DeterministicEventRegistrationRunner();
            runner.Run();
        }

#if VERIFY_INT_ARGS_NOT_NULL

        [TestMethod]
        public void ArgumentsCheck_source()
        {
            Assert.IsNull(StandardPatch<IEnumerable<int>,int>.Create(null), "Expected null if created with null source.");
        }

#endif

        [TestMethod]
        public void EqualityTest()
        {
            EqualityRunner.Run(
                new int[0], new int[0],
                s => StandardPatch<IEnumerable<int>, int>.Create(s),
                "SequencingPatchTransformation<int>"
            );
        }

        [TestMethod]
        public void ConcurrencyTest()
        {
            List<string> source = new List<string>(
                new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "11", "12", "13" }
            );

            List<string> result = new List<string>(
                new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }
            );

            AsyncTestRunnerForCollectionTransformation.Run(
                source.ToArray(),
                result.ToArray(),
                frame => (IVersionedEnumerable<string>)ObservableEnumerable.Patched((System.Collections.IEnumerable)frame),
                "ObservableEnumerable.Patched((System.Collections.IEnumerable)frame)"
            );
        }

#if !SILVERLIGHT
        class BindingListPatchCorrectnessRunner : CollectionTestSequenceRunner<string>
        {
            static List<string> source = new List<string>(
                new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }
            );

            public override List<string> SourceSequence
            {
                get { return source; }
            }

            static List<string> filler = new List<string>(
                new string[] { "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }
            );

            public override List<string> FillerItems
            {
                get { return filler; }
            }

            static List<int> result = new List<int>(
                new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }
            );

            protected override bool RunActions(CollectionTestSequenceRunner<string>.Action firstAction, CollectionTestSequenceRunner<string>.Action secondAction, List<string> targetCopy2, string description, int count)
            {
                var frame = new BindingList<string>(targetCopy2);
                var cvt = ObservableEnumerable.Select(frame, s => int.Parse(s));
                var client = new CollectionTransformationClientNPC<int>();
                client.Source = cvt;

                var manipulator = new BindingListFrame<string>(frame);

                secondAction(manipulator);
                firstAction(manipulator);

                Assert.IsTrue(Enumerable.SequenceEqual(result, client.Buffer), "Expected sequences to be equal at manipulation " + count + ": " + description);

                return true;
            }
        }

        [TestMethod]
        public void BindingListPatchCorrectnessTest()
        {
            var runnr = new BindingListPatchCorrectnessRunner();
            runnr.RunAllPrepPairs();
        }
#endif
    }
}
